package com.gin.kotlin.vegetables_kot.activity

import android.app.DatePickerDialog
import android.app.TimePickerDialog
import android.content.DialogInterface
import android.content.Intent
import android.os.Message
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultLauncher
import androidx.core.widget.addTextChangedListener
import androidx.viewpager2.adapter.FragmentStateAdapter
import com.gin.kotlin.vegetables_kot.R
import com.gin.kotlin.vegetables_kot.adapter.OptionAdapter
import com.gin.kotlin.vegetables_kot.app.App
import com.gin.kotlin.vegetables_kot.base.AlertDialogUtils
import com.gin.kotlin.vegetables_kot.databinding.ActivityMainBinding
import com.gin.kotlin.vegetables_kot.databinding.DialogVegRecoredAddBinding
import com.gin.kotlin.vegetables_kot.enums.MsgWhat
import com.gin.kotlin.vegetables_kot.fragment.VegPageFragment
import com.gin.kotlin.vegetables_kot.network.api.VegRecordApi
import com.gin.kotlin.vegetables_kot.network.forms.VegRecordFormAdd
import com.gin.kotlin.vegetables_kot.network.forms.VegRecordFormUpdate
import com.gin.kotlin.vegetables_kot.network.params.PageParams
import com.gin.kotlin.vegetables_kot.network.params.filter.VegRecordFilter
import com.gin.kotlin.vegetables_kot.network.response.body.VegParamOptions
import com.gin.kotlin.vegetables_kot.network.response.body.VegRecord
import com.gin.kotlin.vegetables_kot.network.response.common.Res
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import java.time.ZoneId
import java.time.ZonedDateTime
import java.time.format.DateTimeFormatter

class MainActivity : AbstractPagerListActivity<ActivityMainBinding>() {
    private lateinit var argument: VegRecordFilter
    private lateinit var api: VegRecordApi
    private var position: MutableList<String>? = null
    private var typeO: MutableList<String>? = null
    private var typeV: MutableList<String>? = null

    override fun refresh() {
        obtainOptions()
        configViewPager2()
    }

    override fun launchPostActivity(launcher: ActivityResultLauncher<Intent>) {
    }

    override fun onCreate() {
        this.api = App.INSTANCE.vegRecordApi
        this.argument = VegRecordFilter()

        b?.autoTvPosition?.addTextChangedListener {
            argument =
                argument.copy(position = it?.toString()?.trim()?.takeIf { t -> t.isNotEmpty() })
        }
        b?.autoTvTypeO?.addTextChangedListener {
            argument = argument.copy(typeO = it?.toString()?.trim()?.takeIf { t -> t.isNotEmpty() })
        }
        b?.autoTvTypeV?.addTextChangedListener {
            argument = argument.copy(typeV = it?.toString()?.trim()?.takeIf { t -> t.isNotEmpty() })
        }
        obtainOptions()
    }

    override fun onCreateOptionsMenu(menu: Menu, menuInflater: MenuInflater) {
        super.onCreateOptionsMenu(menu, menuInflater)
        menuInflater.inflate(R.menu.main, menu)
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        if (item.itemId == R.id.mi_search) {
            configViewPager2()
            return true
        }

        if (item.itemId == R.id.mi_add) {
            openDialogAdd()
            return true
        }

        return super.onOptionsItemSelected(item)
    }

    /**
     * 打开添加弹窗
     */
    private fun openDialogAdd() {
        val binding = DialogVegRecoredAddBinding.inflate(layoutInflater)
        var opZdt = ZonedDateTime.now()

        binding.tvTimeODate.also { tv ->
            tv.text = opZdt.toLocalDate().toString()
            tv.setOnClickListener {
                // 日期选择弹窗
                DatePickerDialog(this, { _, year, month, dayOfMonth ->
                    opZdt = opZdt.withYear(year).withMonth(month + 1).withDayOfMonth(dayOfMonth)
                    tv.text = opZdt.toLocalDate().toString()
                }, opZdt.year, opZdt.monthValue - 1, opZdt.dayOfMonth).show()
            }
        }

        binding.tvTimeOTime.also { tv ->
            tv.text = opZdt.toLocalTime().format(SIMPLE_TIME_FORMATTER)
            tv.setOnClickListener {
                TimePickerDialog(this, { _, hourOfDay, minute ->
                    opZdt = opZdt.withHour(hourOfDay).withMinute(minute)
                    tv.text = opZdt.toLocalTime().format(SIMPLE_TIME_FORMATTER)
                }, opZdt.hour, opZdt.minute, true).show()
            }
        }
        binding.autoTvPosition.setAdapter(OptionAdapter(this, this.position))
        binding.autoTvTypeO.setAdapter(OptionAdapter(this, this.typeO))
        binding.autoTvTypeV.setAdapter(OptionAdapter(this, this.typeV))

        val alertDialog = AlertDialogUtils.builder(
            this,
            "添加记录",
            contentView = binding.root,
            listener = { _, which ->
                if (which == DialogInterface.BUTTON_POSITIVE) {
                    // 发送请求
                    val form = VegRecordFormAdd(
                        position = binding.autoTvPosition.text.toString(),
                        typeO = binding.autoTvTypeO.text.toString(),
                        typeVs = binding.autoTvTypeV.text.toString().split(" ").filter { it.isNotEmpty() },
                        timeO = opZdt.toEpochSecond(),
                        description = binding.etDescription.text.toString()
                    )
                    api.add(form).enqueue(object : Callback<Res<Nothing>?> {
                        override fun onResponse(call: Call<Res<Nothing>?>, response: Response<Res<Nothing>?>) {
                            response.body()?.message?.also { toast(it) }
                            if (response.code() == 200) {
                                b?.viewPager2?.currentItem = 0
                                configViewPager2()
                            }
                        }

                        override fun onFailure(call: Call<Res<Nothing>?>, t: Throwable) {
                            AlertDialogUtils.builder(this@MainActivity, "请求错误", t.localizedMessage).show()
                        }
                    })
                }
            })
            .show()
        // 不能通过点击外部关闭
        alertDialog.setCanceledOnTouchOutside(false)
        val positiveButton = alertDialog.getButton(DialogInterface.BUTTON_POSITIVE)
        positiveButton.isEnabled = false

        listOf(binding.autoTvPosition, binding.autoTvTypeO, binding.autoTvTypeV).forEach {
            it.addTextChangedListener { t -> positiveButton.isEnabled = !t.isNullOrEmpty() && t.toString().trim().isNotEmpty() }
        }
    }

    override fun handleMessage(msg: Message): Boolean {
        if (msg.what == MsgWhat.VEG_RECORD_UPDATE.ordinal) {
            openDialogUpdate(msg.obj as VegRecord)
        }
        return super.handleMessage(msg)
    }

    /**
     * 打开添加弹窗
     */
    private fun openDialogUpdate(record: VegRecord) {
        val uuid = record.uuid ?: ""
        val binding = DialogVegRecoredAddBinding.inflate(layoutInflater)
        var opZdt = record.timeO?.withZoneSameInstant(ZoneId.systemDefault()) ?: ZonedDateTime.now()

        binding.tvTimeODate.also { tv ->
            tv.text = opZdt.toLocalDate().toString()
            tv.setOnClickListener {
                // 日期选择弹窗
                DatePickerDialog(this, { _, year, month, dayOfMonth ->
                    opZdt = opZdt.withYear(year).withMonth(month + 1).withDayOfMonth(dayOfMonth)
                    tv.text = opZdt.toLocalDate().toString()
                }, opZdt.year, opZdt.monthValue - 1, opZdt.dayOfMonth).show()
            }
        }

        binding.tvTimeOTime.also { tv ->
            tv.text = opZdt.toLocalTime().format(SIMPLE_TIME_FORMATTER)
            tv.setOnClickListener {
                TimePickerDialog(this, { _, hourOfDay, minute ->
                    opZdt = opZdt.withHour(hourOfDay).withMinute(minute)
                    tv.text = opZdt.toLocalTime().format(SIMPLE_TIME_FORMATTER)
                }, opZdt.hour, opZdt.minute, true).show()
            }
        }
        binding.autoTvPosition.also { tv ->
            tv.setText(record.position)
            tv.setAdapter(OptionAdapter(this, this.position))
        }
        binding.autoTvTypeO.also { tv ->
            tv.setText(record.typeO)
            tv.setAdapter(OptionAdapter(this, this.typeO))
        }
        binding.autoTvTypeV.also { tv ->
            tv.setText(record.typeV)
            tv.setAdapter(OptionAdapter(this, this.typeV))
        }
        binding.etDescription.setText(record.description)

        val alertDialog = AlertDialogUtils.builder(
            this,
            "修改记录",
            contentView = binding.root,
            listener = { _, which ->
                if (which == DialogInterface.BUTTON_POSITIVE) {
                    // 发送请求
                    val form = VegRecordFormUpdate(
                        uuid = uuid,
                        position = binding.autoTvPosition.text.toString(),
                        typeO = binding.autoTvTypeO.text.toString(),
                        typeV = binding.autoTvTypeV.text.toString(),
                        timeO = opZdt.toEpochSecond(),
                        description = binding.etDescription.text.toString(),
                    )
                    api.update(form).enqueue(object : Callback<Res<Nothing>?> {
                        override fun onResponse(call: Call<Res<Nothing>?>, response: Response<Res<Nothing>?>) {
                            response.body()?.message?.also { toast(it) }
                            if (response.code() == 200) {
                                configViewPager2()
                            }
                        }

                        override fun onFailure(call: Call<Res<Nothing>?>, t: Throwable) {
                            AlertDialogUtils.builder(this@MainActivity, "请求错误", t.localizedMessage).show()
                        }
                    })
                }
            })
            .show()
        // 不能通过点击外部关闭
        alertDialog.setCanceledOnTouchOutside(false)
        val positiveButton = alertDialog.getButton(DialogInterface.BUTTON_POSITIVE)

        listOf(binding.autoTvPosition, binding.autoTvTypeO, binding.autoTvTypeV).forEach {
            it.addTextChangedListener { t -> positiveButton.isEnabled = !t.isNullOrEmpty() && t.toString().trim().isNotEmpty() }
        }
    }

    /**
     * 配置ViewPager2
     */
    private fun configViewPager2() {
        b?.viewPager2?.adapter = object : FragmentStateAdapter(this) {
            override fun getItemCount() = totalPage
            override fun createFragment(position: Int) =
                VegPageFragment.newInstance(PageParams(position + 1), argument)
        }
    }

    /**
     * 请求选项
     */
    private fun obtainOptions() {
        api.options().enqueue(object : Callback<Res<VegParamOptions>?> {
            override fun onResponse(
                call: Call<Res<VegParamOptions>?>,
                response: Response<Res<VegParamOptions>?>
            ) {
                response.body()?.data?.also {
                    this@MainActivity.position = it.position
                    this@MainActivity.typeO = it.typeO
                    this@MainActivity.typeV = it.typeV

                    // 更新下拉选项
                    b?.autoTvPosition?.setAdapter(OptionAdapter(this@MainActivity, it.position))
                    b?.autoTvTypeO?.setAdapter(OptionAdapter(this@MainActivity, it.typeO))
                    b?.autoTvTypeV?.setAdapter(OptionAdapter(this@MainActivity, it.typeV))
                }
            }

            override fun onFailure(call: Call<Res<VegParamOptions>?>, t: Throwable) {
                AlertDialogUtils.builder(this@MainActivity, "请求错误", t.localizedMessage).show()
            }
        })
    }

    override fun handleIntent(intent: Intent) {
    }

    override fun onActivityResult(result: ActivityResult) {
    }

    override fun onResume() {
        super.onResume()
        setToolbarTitle("种菜记录")
    }

    companion object {
        private val SIMPLE_TIME_FORMATTER: DateTimeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss")
    }
}